package testooj3.compatibility;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;









import testooj3.auxiliares.SemanticInterfaceCompatibility;
import testooj3.domain.TClass;
import testooj3.domain.TMethod;
import testooj3.domain.TParameter;
import testooj3.domain.TestoojClassLoader;





/** 
 * @author andres
 */
public class InterfacesCompatibilityChecker implements Runnable {
	protected final int NO_COMPATIBLE = 0;
	protected String summary = "";  //  @jve:decl-index=0:
	protected String summaryList = "";  //  @jve:decl-index=0:
	TClass a; //original class
	TClass b; //candidate class
	protected double maxCompatibilityValue = 0;
	
	
	
	protected Hashtable<String, List<Vector>> compatibilities;  //  @jve:decl-index=0:
	
	private Hashtable<MaximalInterfaceCompatibility, Vector<ParameterCompatibilityPair>> parameterMatching;
	protected String classPathOriginal;
	protected String classPathCandidate;
	protected int cantidadWrappers;
	
	public double getMaxCompatibility() {
		return maxCompatibilityValue;
	}
	
	public InterfacesCompatibilityChecker(String originalClassName, String candidateClassName,
			boolean considerInheritedOperations, String classPathOriginal,
			String classPathCandidate) throws Exception {
		
		
		this.parameterMatching= new Hashtable();
		
		a = TestoojClassLoader.load(originalClassName, classPathOriginal,
				considerInheritedOperations);
		b = TestoojClassLoader.load(candidateClassName, classPathCandidate,
				considerInheritedOperations);
		this.classPathOriginal = classPathOriginal;
		this.classPathCandidate = classPathCandidate;
					
	}
	
	protected void calculateCompatibilitiesNew() throws IOException {
		Vector methods = a.getMethods();
		Vector methodsB = b.getMethods();
		this.compatibilities = new Hashtable<String, List<Vector>>();
		for (int i = 0; i < methods.size(); i++) {
			
			TMethod method = (TMethod) methods.get(i);
			this.compatibilities.put(method.getWholeSignature(), new LinkedList<Vector>());			
			loadCompatibleMethods(i, a, method, b);
		}
		//buildSummary();
	}
	
	
	public void run() {
		try {
			calculateCompatibilitiesNew();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private void loadCompatibleMethods(int c1MethodIndex, TClass c1,TMethod c1Method, TClass c2) throws IOException 
	{
		List<Vector> compatibles = compatibilities.get(c1Method.getWholeSignature());
		int minValue = 999;
		
		double minAdaptabilityGap = 9;	
		Double maxSim = 0.0;
				
		MaximalInterfaceCompatibility maximalInterfaceCompatibility = null;
		Vector<ParameterCompatibilityPair> vecParamCompatibilityPair = null;
		Vector<int[][]> resultParam = null;
		
		for (int i = 0; i < c2.getMethods().size(); i++) {
			
			/* Version vieja, todo es factor de incompatibilidad.
			int paramCase = 0; // no compatible
			int nameCase = 0; // distinct names
			int returnCase = 0; // no compatible
			int excepCase = 3; // no descartamos servicios por incompatibilidad de excepciones
			*/
			// Version nueva, nada es factor de incompatibilidad (todo pasa dijo grondona)
			 
			int paramCase = 4; // no compatible
			int nameCase = 3; // distinct names
			int returnCase = 3; // no compatible
			int excepCase = 3; // no descartamos servicios por incompatibilidad de excepciones
			double adaptabilityGap = 9;
			
			double parameterResult = 0;
									
			TMethod c2Method = c2.getMethod(i);
			
				// Evaluar Parametros
				
				if (c1Method.getParametros().size()<= c2Method.getParametros().size() &&
					c1Method.getParametros().size() >= ((c2Method.getParametros().size())/2)) {																			
					
					if(c1Method.getParametros().size()!=0)
					{
						resultParam =new Vector<int[][]>();
						parameterResult = SemanticInterfaceCompatibility.paramCaseValue(c1Method,c1,c2Method,c2,resultParam,this.classPathOriginal,this.classPathCandidate);
						
						//Version OK
						if(parameterResult >= 2)
							paramCase =1;
						else if(0.5 < parameterResult && parameterResult < 2)
							paramCase=2;
						else if(0.2<parameterResult && parameterResult <= 0.5)
							paramCase =3;
						else if(0<parameterResult && parameterResult <= 0.2)
							paramCase = 4;
						else
							paramCase= 4;					
						
						adaptabilityGap -= parameterResult/2;
						
						//System.out.println("VALOR DE PARAMETROS DIV 2: " + parameterResult);
											
					}
					
					else if(c2Method.getParametros().size()==0){
						
						adaptabilityGap = -2;
						paramCase = 1; //No tiene parametros
					}							
						else
							// paramCase=0;
							paramCase = 4;
					
					if (paramCase != 0) { // Si param distinto NoCompatible =>
											// sigue
						// Evaluar Tipo de Resultado
						String returnTypeM1 = c1Method.getTipo();
						String returnTypeM2 = c2Method.getTipo();
						
						int returnRes = 0; 
						
						if (returnTypeM1.contains(".")){
							returnTypeM1 = returnTypeM1.substring(returnTypeM1.lastIndexOf(".")+1);
						}
						
						if (returnTypeM2.contains(".")){
							returnTypeM2 = returnTypeM2.substring(returnTypeM2.lastIndexOf(".")+1);
						}																	
						
						if (returnTypeM1.equalsIgnoreCase(returnTypeM2)){
							returnCase = 1; // condicion R1
							returnRes = 2;
						}
							
						else if (isSubTyping(returnTypeM1, returnTypeM2)){
							returnCase = 2; // condicion R2
							returnRes = 1;
						}
							
						else if (isSubTypeReturn(c1Method, c2Method)){
							returnCase = 3;
							returnRes = 0;
						}
							
						
						adaptabilityGap -= returnRes;
						if (returnCase != 0) { // Si returnType distinto
												// NoCompatible => sigue
							
							// Evaluar Excepciones
							
							
							int excepResult = 0;
							
							if (c1Method.getLaunchedExceptions().equals(
									c2Method.getLaunchedExceptions())){
								excepCase = 1; // condicion Ec1: E1 /\ E2
								excepResult = 2;
							}							
							else if (c1Method.getLaunchedExceptions().size() == c2Method
									.getLaunchedExceptions().size()) {
								if (isCompatibleExceptions(c1Method, c2Method)){
									excepCase = 2;
									excepResult = 1;
								}
									
								else if (isExistsException(c1Method, c2Method)){
									excepCase = 3;
									excepResult = 0;
								}
									
									
							}
							
							
							excepCase = 1;
							excepResult = 2;
							// Lo dejamos en 1 porque Axis2 genera servicios con excepciones que de otra forma van a resultar incompatibles						
														
							adaptabilityGap-=excepResult;
							
							if (excepCase != 0) { // Si Excepciones distinto
													// NoCompatible => sigue
								// Evaluar Nombre de Metodo
								////System.out.println("Se compara semanticamente: "+ c1Method.getNombre()+ " "+ c2Method.getNombre());
								int[] semanticRes = {0,0,0,0};
								Vector<Vector> termVec = new Vector();
								try{
					    			semanticRes= SemanticInterfaceCompatibility.assessNameCompatibility(c1Method.getNombre(),c2Method.getNombre(),termVec);
					    			
				    			}
				    			catch(Exception e)
				    			{
				    				e.printStackTrace();
				    			}
				    			Double nameResult = SemanticInterfaceCompatibility.compatibleValue(semanticRes, termVec.get(0), termVec.get(1));
				    			if(nameResult>=1)
				    				nameCase = 1;
								else if (nameResult>=0.5 )
									nameCase = 2; 
								else if(nameResult >= 0.2)
									nameCase=3;
								else
									//nameCase=0;
									nameCase=3;
				    			adaptabilityGap -= 2*nameResult;
							}
						}
					}
				}
			Vector level = getLevelCompatibilidad(returnCase, nameCase,
					paramCase, excepCase);
			// Establece el nivel de compatibilidad de Interfaces (syntactica) alcanzado
			Integer nroLevel = (Integer) level.get(0);
			
			if (nroLevel.intValue() != NO_COMPATIBLE) // si es NO_COMPATIBLE
			{
								
				minValue=nameCase+paramCase+excepCase+returnCase;
				
			//	adaptabilityGap += 1; //Sumo uno de acuerdo a la f�rmula. OJO que esto deber�a hacerse al final, pero en el exp. los servicios son single-operation
				if (minAdaptabilityGap != 9){
					// Ya hab�a un minimo
									
					if( (adaptabilityGap < minAdaptabilityGap) && c1Method.getParametros().size()>0 && c2Method.getParametros().size()>0)
					{
						maximalInterfaceCompatibility = new MaximalInterfaceCompatibility(c1Method.getWholeSignature(), c2Method.getWholeSignature());
						vecParamCompatibilityPair = createParamCompatibilityPair(c1Method.getParametros(), c2Method.getParametros(),resultParam);
												
										
						minAdaptabilityGap = adaptabilityGap;
					}
					
					addCompatibleMethod(compatibles, c2Method, level, adaptabilityGap);
					
				}
				else if (adaptabilityGap != 9){ 
					//Este es el 1ero compatible que se encuentra
					
					if (c1Method.getParametros().size()>0 && c2Method.getParametros().size()>0){
						maximalInterfaceCompatibility = new MaximalInterfaceCompatibility(c1Method.getWholeSignature(), c2Method.getWholeSignature());
						vecParamCompatibilityPair = createParamCompatibilityPair(c1Method.getParametros(), c2Method.getParametros(),resultParam);
						minValue=nameCase+paramCase+excepCase+returnCase;
					}
				
					minAdaptabilityGap = adaptabilityGap;
					
					addCompatibleMethod(compatibles, c2Method, level, minAdaptabilityGap);	
				}
				
					
			}
		}	
	
		if(maximalInterfaceCompatibility!=null && vecParamCompatibilityPair!=null)
			parameterMatching.put(maximalInterfaceCompatibility,vecParamCompatibilityPair);
		Collections.sort(compatibles, new InterfaceCompatibilityComparator());		
		if (compatibles.size() > 0) {
			maxCompatibilityValue = (double) compatibles.get(0).get(3);
		}
	}

	
	/*protected void buildSummary() {
		Enumeration vectores = this.compatibilities.elements();
		int max = 0;
		while (vectores.hasMoreElements()) {
			Vector v = (Vector) vectores.nextElement();
			if (v.size() > max)
				max = v.size();
		}

		Enumeration<String> keys = this.compatibilities.keys();
		StringBuffer sb = new StringBuffer("<table border=1 FONTSIZE='3'>");
		sb.append("<tr><th><FONT SIZE='3'>");
		sb.append(a.getName());
		sb.append("</FONT></th>");
		sb.append("<th colspan=");
		sb.append(max);
		sb.append("><FONT SIZE='3'>");
		sb.append(b.getName());
		sb.append("</FONT></th></tr>");
		while (keys.hasMoreElements()) {
			String methodSignature = keys.nextElement();
			Vector compatibles = (Vector) compatibilities.get(methodSignature);
			// Forma 1era celda de fila - el metodo original de a
			if (!compatibles.isEmpty())
				sb.append("<tr><td bgcolor=\"#F0F8FF\"><FONT SIZE='3'>"); // Hay
																			// compatibles
																			// ->
																			// celeste
			else
				sb.append("<tr><td bgcolor=\"#FF6347\"><FONT SIZE='3'>");// No
																			// Hay
																			// compatibles
																			// ->
																			// rojo
			sb.append(methodSignature);
			sb.append("</FONT></td>");

			// Forma el resto de la fila - los compatibles de b
			for (int i = 0; i < compatibles.size(); i++) {
				Vector compToPrint = (Vector) ((Vector) compatibles.get(i))
						.clone();
				TMethod bMethod = (TMethod) compToPrint.get(2);
				compToPrint.remove(2);
				compToPrint.add(2, bMethod.getWholeSignature());
				//System.out.println("OO  "+compToPrint.get(0));
				if (compToPrint.get(0).equals(1)) // si es "exact" Nro caso 1
					sb.append("<td bgcolor=\"#F0F8FF\"><FONT SIZE='3'>");// Hay
																			// iguales
																			// ->
																			// celeste
				else
					sb.append("<td><FONT SIZE='3'>");// El resto -> blanco
				sb.append(compToPrint.toString());
				sb.append("</FONT></td>");
			}
			sb.append("<td>");
						
			for (int i = 0; i < max - compatibles.size(); i++)
				sb.append("<td></td>");
			
			
			//Matching parametros
			sb.append("<td>");
			String match = "";
			Vector v = parameterMatching.get(new MaximalInterfaceCompatibility(methodSignature, ""));
			if(v!=null && v.size()>0)
				sb.append(v.toString());
			sb.append("</td>");
			//fin Matching parametros
			sb.append("</tr>");
		}
		sb.append("</table>");
		summary = sb.toString();
	}

		*/
	private Vector<ParameterCompatibilityPair> createParamCompatibilityPair(Vector<TParameter> c1MethodParameters , Vector<TParameter> c2MethodParameters, Vector<int[][]> vecResultParam) {
		
		Vector<ParameterCompatibilityPair> ret= new Vector();
		ParameterCompatibilityPair aux;
		int[][] resultParam = vecResultParam.get(0);
		if(resultParam!=null)
			for(int i=0; i<resultParam.length; i++)
			{
				aux= new ParameterCompatibilityPair(c1MethodParameters.get(resultParam[i][0]).getMNombre(), c1MethodParameters.get(resultParam[i][0]).getTipo(), c2MethodParameters.get(resultParam[i][1]).getMNombre(),c2MethodParameters.get(resultParam[i][1]).getTipo());
				ret.add(aux);
			}
		return ret;
	}


	private Vector getLevelCompatibilidad(int returnCase, int nameCase,
			int paramCase, int excepCase) {
		// Idenfica el caso de compatibilidad
		Vector level = new Vector();
		if (paramCase != 0 && returnCase != 0 && excepCase != 0 && nameCase !=0) {
			String rCase = "R" + returnCase;
			String nCase = "N" + nameCase;
			String pCase = "P" + paramCase;
			String eCase = "E" + excepCase; 
			level.add(rCase);
			level.add(nCase);
			level.add(pCase);
			level.add(eCase);

			// 54 Casos nuevos y autom�ticos, chequeados. R puede ser 1 � 2. N,
			// P, E pueden ser 1,2 � 3.

			if (returnCase == 1 && nameCase == 1 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 1); // "exact" - Caso 1
				level.add(1, "exact");
				return level;
			}

			// --[ N_Exact
			// ]-----------------------------------------------------------------------

			if (returnCase == 1 && nameCase == 1 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 2); // "n_exact_1" - Caso 2
				level.add(1, "n_exact_1");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 3); // "n_exact_2" - Caso 3
				level.add(1, "n_exact_2");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 4); // "n_exact_3" - Caso 4
				level.add(1, "n_exact_3");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 5); // "n_exact_4" - Caso 5
				level.add(1, "n_exact_4");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 6); // "n_exact_5" - Caso 6
				level.add(1, "n_exact_5");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 7); // "n_exact_6" - Caso 7
				level.add(1, "n_exact_6");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 8); // "n_exact_7" - Caso 8
				level.add(1, "n_exact_7");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 9); // "n_exact_8" - Caso 9
				level.add(1, "n_exact_8");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 10); // "n_exact_9" - Caso 10
				level.add(1, "n_exact_9");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 11); // "n_exact_10" - Caso 11
				level.add(1, "n_exact_10");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 12); // "n_exact_11" - Caso 12
				level.add(1, "n_exact_11");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 13); // "n_exact_12" - Caso 13
				level.add(1, "n_exact_12");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 14); // "n_exact_13" - Caso 14
				level.add(1, "n_exact_13");
				return level;
			}

			//Manual
			if (returnCase == 3 && nameCase == 1 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 15); // "n_exact_14" - Caso 15
				level.add(1, "n_exact_14");
				return level;
			}
			
			// --[ Soft
			// ]--------------------------------------------------------------------------

			if (returnCase == 1 && nameCase == 2 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 16); // "soft_1" - Caso 16
				level.add(1, "soft_1");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 17); // "soft_2" - Caso 17
				level.add(1, "soft_2");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 18); // "soft_3" - Caso 18
				level.add(1, "soft_3");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 19); // "soft_4" - Caso 19
				level.add(1, "soft_4");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 20); // "soft_5" - Caso 20
				level.add(1, "soft_5");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 21); // "soft_6" - Caso 21
				level.add(1, "soft_6");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 22); // "soft_7" - Caso 22
				level.add(1, "soft_7");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 24); // "soft_9" - Caso 24
				level.add(1, "soft_9");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 25); // "soft_10" - Caso 25
				level.add(1, "soft_10");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 26); // "soft_11" - Caso 26
				level.add(1, "soft_11");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 27); // "soft_12" - Caso 27
				level.add(1, "soft_12");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 28); // "soft_13" - Caso 28
				level.add(1, "soft_13");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 29); // "soft_14" - Caso 29
				level.add(1, "soft_14");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 33); // "soft_18" - Caso 33
				level.add(1, "soft_18");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 34); // "soft_19" - Caso 34
				level.add(1, "soft_19");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 35); // "soft_20" - Caso 35
				level.add(1, "soft_20");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 36); // "soft_21" - Caso 36
				level.add(1, "soft_21");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 37); // "soft_22" - Caso 37
				level.add(1, "soft_22");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 38); // "soft_23" - Caso 38
				level.add(1, "soft_23");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 41); // "soft_26" - Caso 41
				level.add(1, "soft_26");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 42); // "soft_27" - Caso 42
				level.add(1, "soft_27");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 43); // "soft_28" - Caso 43
				level.add(1, "soft_28");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 44); // "soft_29" - Caso 44
				level.add(1, "soft_29");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 45); // "soft_30" - Caso 45
				level.add(1, "soft_30");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 46); // "soft_31" - Caso 46
				level.add(1, "soft_31");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 47); // "soft_32" - Caso 47
				level.add(1, "soft_32");
				return level;
			}

			//Manual
			if (returnCase == 1 && nameCase == 1 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 23); // "soft_8" - Caso 23
				level.add(1, "soft_8");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 30); // "soft_15" - Caso 30
				level.add(1, "soft_15");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 31); // "soft_16" - Caso 31
				level.add(1, "soft_16");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 32); // "soft_17" - Caso 32
				level.add(1, "soft_17");
				return level;
			}
			if (returnCase == 1 && nameCase == 1 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 39); // "soft_24" - Caso 39
				level.add(1, "soft_24");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 40); // "Soft_25" - Caso 40
				level.add(1, "soft_25");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 48); // "Soft_33" - Caso 48
				level.add(1, "soft_33");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 49); // "soft_34" - Caso 49
				level.add(1, "soft_34");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 50); // "soft_35" - Caso 50
				level.add(1, "soft_35");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 1
					&& excepCase == 1) {
				level.add(0, 51); // "soft_36" - Caso 51
				level.add(1, "soft_36");
				return level;
			}
			if (returnCase ==3 && nameCase == 1 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 52); // "soft_37" - Caso 52
				level.add(1, "soft_37");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 53); // "soft_38" - Caso 53
				level.add(1, "soft_38");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 54); // "soft_39" - Caso 54
				level.add(1, "soft_39");
				return level;
			}

			
			// --[ N_Soft
			// ]------------------------------------------------------------------------

			if (returnCase == 1 && nameCase == 3 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 55); // "n_soft_1" - Caso 55
				level.add(1, "n_soft_1");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 56); // "n_soft_2" - Caso 56
				level.add(1, "n_soft_2");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 57); // "n_soft_3" - Caso 57
				level.add(1, "n_soft_3");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 61); // "n_soft_7" - Caso 61
				level.add(1, "n_soft_7");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 62); // "n_soft_8" - Caso 62
				level.add(1, "n_soft_8");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 63); // "n_soft_9" - Caso 63
				level.add(1, "n_soft_9");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 64); // "n_soft_10" - Caso 64
				level.add(1, "n_soft_10");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 65); // "n_soft_11" - Caso 65
				level.add(1, "n_soft_11");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 66); // "n_soft_12" - Caso 66
				level.add(1, "n_soft_12");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 77); // "n_soft_23" - Caso 77
				level.add(1, "n_soft_23");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 80); // "n_soft_26" - Caso 80
				level.add(1, "n_soft_26");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 81); // "n_soft_27" - Caso 81
				level.add(1, "n_soft_27");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 82); // "n_soft_28" - Caso 82
				level.add(1, "n_soft_28");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 95); // "n_soft_41" - Caso 95
				level.add(1, "n_soft_41");
				return level;
			}

			//Manual
			if (returnCase == 1 && nameCase == 1 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 58); // "n_soft_4" - Caso 58
				level.add(1, "n_soft_4");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 59); // "n_soft_5" - Caso 59
				level.add(1, "n_soft_5");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 60); // "n_soft_6" - Caso 60
				level.add(1, "n_soft_6");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 67); // "n_soft_13" - Caso 67
				level.add(1, "n_soft_13");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 68); // "n_soft_14" - Caso 68
				level.add(1, "n_soft_14");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 69); // "n_soft_15" - Caso 69
				level.add(1, "n_soft_15");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 1
					&& excepCase == 2) {
				level.add(0, 70); // "n_soft_16" - Caso 70
				level.add(1, "n_soft_16");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 71); // "n_soft_17" - Caso 71
				level.add(1, "n_soft_17");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 2
					&& excepCase == 2) {
				level.add(0, 72); // "n_soft_18" - Caso 72
				level.add(1, "n_soft_18");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 2
					&& excepCase == 1) {
				level.add(0, 73); // "n_soft_19" - Caso 73
				level.add(1, "n_soft_19");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 74); // "n_soft_20" - Caso 74
				level.add(1, "n_soft_20");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 75); // "n_soft_21" - Caso 75
				level.add(1, "n_soft_21");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 76); // "n_soft_22" - Caso 76
				level.add(1, "n_soft_22");
				return level;
			}
			if (returnCase == 1 && nameCase == 2 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 78); // "n_soft_24" - Caso 78
				level.add(1, "n_soft_24");
				return level;
			}

			if (returnCase == 1 && nameCase == 3 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 79); // "n_soft_25" - Caso 79
				level.add(1, "n_soft_25");
				return level;
			}
			if (returnCase == 2 && nameCase == 1 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 83); // "n_soft_29" - Caso 83
				level.add(1, "n_soft_29");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 84); // "n_soft_30" - Caso 84
				level.add(1, "n_soft_30");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 85); // "n_soft_31" - Caso 85
				level.add(1, "n_soft_31");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 1
					&& excepCase == 3) {
				level.add(0, 86); // "n_soft_32" - Caso 86
				level.add(1, "n_soft_32");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 87); // "n_soft_33" - Caso 87
				level.add(1, "n_soft_33");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 88); // "n_soft_34" - Caso 88
				level.add(1, "n_soft_34");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 89); // "n_soft_35" - Caso 89
				level.add(1, "n_soft_35");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 90); // "n_soft_36" - Caso 90
				level.add(1, "n_soft_36");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 3
					&& excepCase == 1) {
				level.add(0, 91); // "n_soft_37" - Caso 91
				level.add(1, "n_soft_37");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 92); // "n_soft_38" - Caso 92
				level.add(1, "n_soft_38");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 93); // "n_soft_39" - Caso 93
				level.add(1, "n_soft_39");
				return level;
			}
			if (returnCase == 1 && nameCase == 3 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 94); // "n_soft_40" - Caso 94
				level.add(1, "n_soft_40");
				return level;
			}
			if (returnCase == 2 && nameCase == 2 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 96); // "n_soft_3" - Caso 57
				level.add(1, "n_soft_42");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 97); // "n_soft_43" - Caso 97
				level.add(1, "n_soft_43");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 2
					&& excepCase == 3) {
				level.add(0, 98); // "n_soft_44" - Caso 98
				level.add(1, "n_soft_44");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 99); // "n_soft_45" - Caso 99
				level.add(1, "n_soft_45");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 3
					&& excepCase == 2) {
				level.add(0, 100); // "n_soft_46" - Caso 100
				level.add(1, "n_soft_46");
				return level;
			}
			if (returnCase == 3 && nameCase == 1 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 101); // "n_soft_47" - Caso 101
				level.add(1, "n_soft_47");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 102); // "n_soft_48" - Caso 102
				level.add(1, "n_soft_48");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 4
					&& excepCase == 1) {
				level.add(0, 103); // "n_soft_49" - Caso 103
				level.add(1, "n_soft_49");
				return level;
			}
			if (returnCase == 2 && nameCase == 3 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 104); // "n_soft_50" - Caso 104
				level.add(1, "n_soft_50");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 3
					&& excepCase == 3) {
				level.add(0, 105); // "n_soft_51" - Caso 105
				level.add(1, "n_soft_51");
				return level;
			}
			if (returnCase == 3 && nameCase == 2 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 106); // "n_soft_52" - Caso 106
				level.add(1, "n_soft_52");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 4
					&& excepCase == 2) {
				level.add(0, 107); // "n_soft_53" - Caso 107
				level.add(1, "n_soft_53");
				return level;
			}
			if (returnCase == 3 && nameCase == 3 && paramCase == 4
					&& excepCase == 3) {
				level.add(0, 108); // "n_soft_54" - Caso 108
				level.add(1, "n_soft_54");
				return level;
			}
			
			level.add(0, 109); // Tener en cuenta el Sort para poner mas
								// numeros
			level.add(1, "misterioso");
		} else {
			level.add(new Integer(NO_COMPATIBLE));
		}
		return level;
	}
	
	
	
	

	private boolean isCompatibleExceptions(TMethod c1Method, TMethod c2Method) {
		boolean allUsed = true;
		int max1 = c1Method.getLaunchedExceptions().size();
		int max2 = c2Method.getLaunchedExceptions().size();
		if (max1 == max2) {
			if (max1 != 0) {
				boolean[] used = new boolean[max1];
				for (int j = 0; j < max1; j++)
					used[j] = false;
				for (int j = 0; j < max1; j++) {
					String m1Excep = c1Method.getLaunchedExceptions().get(j)
							.toString();
					for (int k = 0; k < max2; k++) {
						String m2Excep = c2Method.getLaunchedExceptions()
								.get(k).toString();
						if (m1Excep.equals(m2Excep) && !used[k])
							used[k] = true;
					}
				}
				for (int k = 0; k < used.length; k++)
					allUsed = allUsed && used[k];
			}
			return allUsed;
		} else
			return false;
	}

	private boolean isExistsException(TMethod c1Method, TMethod c2Method) {
		if (c1Method.getLaunchedExceptions().size() != 0) {
			if (c2Method.getLaunchedExceptions().size() == 0) {
				return false;
			}
		}
		return true;
	}

		
	private boolean isSubTypeReturn(TMethod c1Method, TMethod c2Method) {
		String tipo1;
		String tipo2;

		if (!(esPrimitivo(c1Method.getTipo()))
				&& !(esPrimitivo(c2Method.getTipo()))) {

			try {

				java.lang.reflect.Field[] f1 = c1Method.getTrueClass().getFields();
				java.lang.reflect.Field[] f2 = c2Method.getTrueClass().getFields();

				if (!(f1.length == f2.length))
					return false;

				boolean[] result = new boolean[f1.length]; // array de boolean

				for (int j = 0; j < f2.length; j++) {
					result[j] = false;
				}

				for (int i = 0; i < f1.length; i++) {

					tipo1 = f1[i].getType().toString();
					tipo2 = f2[i].getType().toString();

					if (tipo1.contains("."))
						tipo1 = tipo1.substring(tipo1.lastIndexOf(".") + 1);
					if (tipo2.contains("."))
						tipo2 = tipo2.substring(tipo2.lastIndexOf(".") + 1);

					result[i] = tipo1.equalsIgnoreCase(tipo2)
							|| isSubTyping(tipo1, tipo2);

				}

				for (int i = 0; i < f1.length; i++) {
					if (result[i] == false)
						return false;
				}
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
			return true;
		}
		return false;
	}

	
	// CLASES ENVOLVENTES - en orden de menor a mayor capacidad.

	// byte --> Byte
	// short --> Short
	// char --> Character
	// int --> Integer
	// long --> Long
	// float --> Float
	// double --> Double
	// �BOOLEAN?

	// Se incluyeron todas las conversiones sin p�rdida de precision, seg�n
	// nueva def. R2
	// y la compatibilidad de String con cualquier tipo.
	// M.G. 14/09/2010 Agregados arrays de tipos simples EN PARAMETROS.
	// Significado:
	// [B --> array de byte
	// [S --> array de short
	// [I --> array de int
	// [J --> array de long, prestar atencion! es J y no L como uno supondr�a!
	// [F --> array de float
	// [D --> array de double

	public static boolean isSubTyping(String type1, String type2) {
		boolean res = false;
		String lstByte = "byte,Byte,short,Short,int,Integer,long,Long,float,Float,double,Double,String";
		String lstShort = "short,Short,int,Integer,long,Long,float,Float,double,Double,String";
		String lstInt = "int,Integer,long,Long,float,Float,java.lang.double,java.lang.Double,double,Double,String";
		String lstLong = "long,Long,float,Float,double,Double,String";
		String lstFloat = "float,Float,double,Double,java.lang.String";
		String lstChar = "char,Character,String";
		//String lstDouble = "double,Double,String";
	//	String lstDouble = "java.lang.double,java.lang.Double,double,Double,long,Long,String,int,Integer";
		String lstDouble = "java.lang.double,java.lang.Double,double,Double,long,Long,String";
		String lstarrayByte = "[B,[S,[I,[J,[F,[D";
		String lstarrayShort = "[S,[I,[J,[F,[D";
		String lstarrayInt = "[I,[J,[F,[D";
		String lstarrayLong = "[J,[F,[D";
		String lstarrayFloat = "[F,[D";
		String lstarrayDouble = "[D";
		String lstarrayChar = "[C";

		// Si el tipo esperado es String, aceptamos cualquier cosa
		if (type1.equalsIgnoreCase("java.lang.String") || type1.equalsIgnoreCase("String")) {
			res = true;
			return res;
		}
		if((type1.equalsIgnoreCase("boolean")) && ((type2.equalsIgnoreCase("java.lang.String")) || (type2.equalsIgnoreCase("String")))){
			return true;
		}
		// An�lisis de tipos primitivos
		if ((type1 == "char") || (type1 == "Character"))
			if (lstChar.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if ((type1 == "byte") || (type1 == "Byte"))
			if (lstByte.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if ((type1 == "short") || (type1 == "Short"))
			if (lstShort.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if ((type1 == "int") || (type1 == "Integer"))
			if (lstInt.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if ((type1 == "long") || (type1 == "Long"))
			if (lstLong.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if ((type1 == "float") || (type1 == "Float"))
			if (lstFloat.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		//if ((type1 == "double") || (type1 == "Double"))
		if (type1.toLowerCase().equals("java.lang.double") || (type1.equals("java.lang.Double")) || (type1.equalsIgnoreCase("double")) || (type1.equalsIgnoreCase("Double")))
			if (lstDouble.indexOf(type2) != -1) {
				res = true;
				return res;
			}

		// // Analisis de ARRAYS de tipos primitivos!
		if (type1 == "[C")
			if (lstarrayChar.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if (type1 == "[B")
			if (lstarrayByte.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if (type1 == "[S")
			if (lstarrayShort.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if (type1 == "[I")
			if (lstarrayInt.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if (type1 == "[J")
			if (lstarrayLong.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if (type1 == "[F")
			if (lstarrayFloat.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		if (type1 == "[D")
			if (lstarrayDouble.indexOf(type2) != -1) {
				res = true;
				return res;
			}
		return res;
	}

	private void addCompatibleMethod(List<Vector> compatibles, TMethod c2Method, Vector level, double adaptabilityGap) {
		// no envio el HashTable, sino solo el vector..
		// level.add(2,c2Method.getWholeSignature()); // nivel de compatibility
		level.add(2, c2Method);
		//level.add(3,adaptabilityGap);
		level.add(3,adaptabilityGap);
		
		

		if (compatibles == null) {
			compatibles = new Vector();
		}
		compatibles.add(level);
	}

	
	/**
	 * -----------------------------------------------------------------
	 * Ordenamiento en O(n). Se usa cuando las claves de b�squeda est�n dentro
	 * de un rango determinado (finito y conocido). Algoritmo: enumeraci�n por
	 * Distribuci�n
	 */

	public Vector getSortedVector(Vector a, int rango) {
		int max = a.size();
		Vector[] salida = new Vector[max];
		Integer clave = new Integer(0);
		int[] count = new int[rango];

		for (int i = 0; i < max; i++) {
			// cuenta las veces que se repite una clave en count.
			clave = (Integer) ((Vector) a.get(i)).get(0);
			count[clave.intValue()]++;
		}

		for (int i = 1; i < rango; i++) {
			// calcula la posicion m�s a la derecha de una clave.+1
			count[i] = count[i - 1] + count[i];
		}

		for (int i = max - 1; i >= 0; i--) {
			// ubica al elemento en la posicion que corresponde.
			clave = (Integer) ((Vector) a.get(i)).get(0);
			int j = count[clave.intValue()] - 1;
			salida[j] = (Vector) a.get(i);
			count[clave.intValue()]--;
		}

		Vector resultado = new Vector(max);
		for (int i = 0; i < max; i++) {
			resultado.add(salida[i]);
		}

		return resultado;
	}

	public String getSummary() {
		return summary;
	}

	public String getSummaryList() {
		return summaryList;
	}

	public Hashtable getCompatibilities() {
		return compatibilities;
	}

	//compara dos objetos de una clase cualquiera, comparando el valor de sus atributos
		public static boolean comparar(TParameter o1, TParameter o2, String pathC1, String pathC2) {

		Class claseActual;
		Class claseNueva;
		boolean esSubstring;    	
		String tipo1;
		String tipo2;
		
		// Ac� habria que poner la parte donde se prepara el classpath 
		// en forma de url, para poder cargar las clases verdaderas de los TParameter
		// que estan siendo comparados. Por ahora anda PORQUE AGREGU� EL PROYECTO AL CLASSPATH!
		
	  boolean iguales=true;
	  
	  try{
		  		  
		  
		    URL[] urls= TestoojClassLoader.prepareURLs(pathC1);
		    URL[] urls2= TestoojClassLoader.prepareURLs(pathC2);
			URLClassLoader loader=new URLClassLoader(urls);
			URLClassLoader loader2=new URLClassLoader(urls2);
			if (esPrimitivo(o1.getTipo()) || esPrimitivo(o2.getTipo())) {
				return o1.getTipo().equals(o2.getTipo());
			}
			claseActual = loader.loadClass(o1.getTipo());
	        claseNueva = loader2.loadClass(o2.getTipo());	  		
	  
	  	Field[] f1=claseActual.getFields();                               
	  	Field[] f2=claseNueva.getFields();
	  	
	  	if (!(f1.length == f2.length)) return false;
	  	
	  	boolean[] result = new boolean[f1.length];   // array de 12 boolean
	  	
	  	for (int j=0; j<f2.length; j++){result[j] = false;}        	
	  
	  	for (int i=0;  i<f1.length;i ++){
	  	
      
	      
	  		tipo1 = f1[i].getType().toString();
	  		tipo2 = f2[i].getType().toString();            		
	  		
	  		if (tipo1.contains(".")) tipo1 = tipo1.substring(tipo1.lastIndexOf(".") + 1);
	  		if (tipo2.contains(".")) tipo2 = tipo2.substring(tipo2.lastIndexOf(".") + 1);
	  		
      
	  		result[i] = tipo1.equals(tipo2) || isSubTyping(tipo1,tipo2);                        
	      
	  	}                
	  
	  	for (int i=0;iguales && i<f1.length;i ++){
	  		
       	
	  		if (result[i] == false) return false;
	  		
	  	}
	  	return true;        
	  
	  }  
	  catch( Exception e){
	  	e.printStackTrace();
	  	return false;
	  }           
	}
	
	public static boolean esPrimitivo(String tipo) {
		if (tipo.startsWith("["))
		   		tipo=tipo.substring (2, tipo.length());
			if (tipo.startsWith ("java.lang.")) 
		           tipo=tipo.substring (tipo.lastIndexOf (".")+1,tipo.length ());
			return tipo.equals("byte") || tipo.equals("short") || tipo.equals("int") || 
		   		tipo.equals("long") || tipo.equals("char") || tipo.equals("float") || 
		   		tipo.equals("double") || tipo.equals("boolean") || tipo.equals("String") ||
		   		tipo.equals("Byte") || tipo.equals("Short") || tipo.equals("Integer") || 
		   		tipo.equals("Long") || tipo.equals("Character") || tipo.equals("Float") || 
		   		tipo.equals("Double") || tipo.equals("Boolean");
		 }
		    	
} // Fin de Clase

